package model.courtier;

import java.util.ArrayList;
import org.hibernate.SQLQuery;
import model.donnee.Annonce;
import model.donnee.Film;
import model.donnee.Recherche;
import model.singleton.HibernateUtil;

public class DAOFilm {

	public DAOFilm() { }

	/****
	 * getFilm : Cette méthode permet de récupérer le film à l'aide du numéro de
	 * film.
	 * 
	 * @param idFilm
	 *            Le numéro du film.
	 * @return Le film.
	 */
	public static Film getFilm(int idFilm) {
		// La requête envoyée à Hibernate.
		String query = "SELECT f.* FROM Film f WHERE f.idFilm = " + idFilm;

		// Récupère les données de la base de données à l'aide d'Hibernate.
		ArrayList<Film> films = (ArrayList<Film>) HibernateUtil.requete(query,
				Film.class);

		return films.get(0);
	}

	/****
	 * getFilms : Cette méthode est utilisée pour récupérer une liste de film à
	 * partir d'un objet de recherche.
	 * 
	 * @param recherche
	 *            Un objet contenant des champs de recherche.
	 * @return Les films répondant à la recherche.
	 */
	public static ArrayList<Film> getFilms(Recherche recherche) {
		String query = "SELECT f.* FROM FILM f WHERE ";
		SQLQuery sqlQuery = null;

		int anneeMin = Integer.MIN_VALUE;
		int anneeMax = Integer.MAX_VALUE;

		// Valide s'il faut faire la recherche avec une année minimum du film.
		if (recherche.getAnneeMin() != null
				&& !recherche.getAnneeMin().isEmpty()) {
			try {
				anneeMin = Integer.parseInt(recherche.getAnneeMin());
			} catch (Exception e) {
			}
		}

		// Valide s'il faut faire la recherche avec une année maximum du film.
		if (recherche.getAnneeMax() != null
				&& !recherche.getAnneeMax().isEmpty()) {
			try {
				anneeMax = Integer.parseInt(recherche.getAnneeMax());
			} catch (Exception e) {
			}
		}
		
		query += "f.ANNEE BETWEEN :anneeMin AND :anneeMax ";

		// Valide s'il y a des titres à rechercher.
		if (recherche.countTitre() > 0)
			query += "AND (";
		for(int i = 0; i < recherche.countTitre() ; ++i)
		{
			query += "UPPER(f.TITRE) LIKE UPPER(:titre" + i + ") ";
			if (i != recherche.countTitre() - 1)
				query += "OR ";
			else
				query += ") ";
		}

		// Valide s'il y a des langues à rechercher.
		if (recherche.countLangue() > 0)
			query += "AND (";
		for(int i = 0; i < recherche.countLangue() ; ++i)
		{
			query += "UPPER(f.LANGUE) LIKE UPPER(:langue" + i + ") ";
			if (i != recherche.countLangue() - 1)
				query += "OR ";
			else
				query += ") ";
		}

		// Valide s'il y a des pays à rechercher.
		if (recherche.countPays() > 0)
			query += "AND (";
		for(int i = 0; i < recherche.countPays() ; ++i)
		{
			query += "UPPER(:pays" + i + ") IN (SELECT UPPER(p.NOMPAYS) FROM PAYS p INNER JOIN PAYSFILM pf ON p.IDPAYS = pf.IDPAYS WHERE pf.IDFILM = f.IDFILM) ";
			if (i != recherche.countPays() - 1)
				query += "OR ";
			else
				query += ") ";
		}

		// Valide s'il y a des genres à rechercher.
		if (recherche.countGenre() > 0)
			query += "AND (";
		for(int i = 0; i < recherche.countGenre() ; ++i)
		{
			query += "UPPER(:genre" + i + ") IN (SELECT UPPER(g.NOM) FROM GENRE g INNER JOIN FILMGENRE fg ON g.IDGENRE = fg.IDGENRE WHERE fg.IDFILM = f.IDFILM) ";
			if (i != recherche.countGenre() - 1)
				query += "OR ";
			else
				query += ") ";
		}

		// Valide s'il y a des réalisateurs à rechercher.
		if (recherche.countRealisateur() > 0)
			query += "AND (";
		for(int i = 0; i < recherche.countRealisateur() ; ++i)
		{
			query += "EXISTS (SELECT pers.IDPERSONNE FROM PERSONNE pers " + 
					 "INNER JOIN MEMBREEXECUTIF me ON pers.IDPERSONNE = me.IDPERSONNE " +
					 "INNER JOIN MEMBREFILM mf ON mf.IDMEMBREEXECUTIF = me.IDMEMBREEXECUTIF " +
					 "WHERE mf.ROLE = 'Réalisateur' AND mf.IDFILM = f.IDFILM AND UPPER(pers.PRENOM || ' ' || pers.NOM) LIKE UPPER(:realisateur" + i + ")) ";
			if (i != recherche.countRealisateur() - 1)
				query += "OR ";
			else
				query += ") ";
		}

		// Valide s'il y a des acteurs à rechercher.
		if (recherche.countActeur() > 0)
			query += "AND (";
		for(int i = 0; i < recherche.countActeur() ; ++i)
		{
			query += "EXISTS (SELECT pers.IDPERSONNE FROM PERSONNE pers " + 
					 "INNER JOIN MEMBREEXECUTIF me ON pers.IDPERSONNE = me.IDPERSONNE " +
					 "INNER JOIN MEMBREFILM mf ON mf.IDMEMBREEXECUTIF = me.IDMEMBREEXECUTIF " +
					 "WHERE mf.ROLE != 'Réalisateur' AND mf.IDFILM = f.IDFILM AND UPPER(pers.PRENOM || ' ' || pers.NOM) LIKE UPPER(:acteur" + i + ")) ";
			if (i != recherche.countActeur() - 1)
				query += "OR ";
			else
				query += ") ";
		}
		
		sqlQuery = HibernateUtil.getSession().createSQLQuery(query);
		sqlQuery.setParameter("anneeMin", anneeMin);
		sqlQuery.setParameter("anneeMax", anneeMax);
		for(int i = 0; i < recherche.countTitre() ; ++i){
			sqlQuery.setParameter("titre" + i, "%" + recherche.getTitre(i) + "%");
		}
		for(int i = 0; i < recherche.countLangue() ; ++i){
			sqlQuery.setParameter("langue" + i, "%" + recherche.getLangue(i) + "%");
		}
		for(int i = 0; i < recherche.countPays() ; ++i){
			sqlQuery.setParameter("pays" + i, recherche.getPays(i));
		}
		for(int i = 0; i < recherche.countGenre() ; ++i){
			sqlQuery.setParameter("genre" + i, recherche.getGenre(i));
		}
		for(int i = 0; i < recherche.countRealisateur() ; ++i){
			sqlQuery.setParameter("realisateur" + i, "%" + recherche.getRealisateur(i) + "%");
		}
		for(int i = 0; i < recherche.countActeur() ; ++i){
			sqlQuery.setParameter("acteur" + i, "%" + recherche.getActeur(i) + "%");
		}
		
		System.out.println(sqlQuery.getQueryString());

		ArrayList<Film> films = (ArrayList<Film>) sqlQuery.addEntity(Film.class).list();	
		
		return films;
	}
}
